using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Identity;
using Volo.Abp.MultiTenancy;
using Volo.Abp.Domain.Entities.Auditing;

namespace MatrixFramework.Shared.Domain.Users
{
    /// <summary>
    /// Matrix Framework应用用户
    /// 继承ABP Identity用户，扩展企业级功能
    /// </summary>
    public class AppUser : IdentityUser, IMultiTenant, IFullAuditedObject
    {
        /// <summary>
        /// 租户ID
        /// </summary>
        public Guid? TenantId { get; set; }

        #region 基础信息

        /// <summary>
        /// 真实姓名
        /// </summary>
        [StringLength(128)]
        public string RealName { get; set; }

        /// <summary>
        /// 头像URL
        /// </summary>
        [StringLength(512)]
        public string AvatarUrl { get; set; }

        /// <summary>
        /// 用户状态
        /// </summary>
        public UserStatus Status { get; set; } = UserStatus.Active;

        /// <summary>
        /// 用户类型
        /// </summary>
        public UserType UserType { get; set; } = UserType.Regular;

        /// <summary>
        /// 员工编号
        /// </summary>
        [StringLength(64)]
        public string EmployeeNumber { get; set; }

        /// <summary>
        /// 部门ID
        /// </summary>
        public Guid? DepartmentId { get; set; }

        /// <summary>
        /// 职位
        /// </summary>
        [StringLength(128)]
        public string Position { get; set; }

        /// <summary>
        /// 直接上级ID
        /// </summary>
        public Guid? ManagerId { get; set; }

        #endregion

        #region 联系信息

        /// <summary>
        /// 手机号码
        /// </summary>
        [Phone]
        [StringLength(32)]
        public string PhoneNumber { get; set; }

        /// <summary>
        /// 手机号码是否已验证
        /// </summary>
        public bool PhoneNumberConfirmed { get; set; }

        /// <summary>
        /// 备用邮箱
        /// </summary>
        [EmailAddress]
        [StringLength(256)]
        public string AlternateEmail { get; set; }

        /// <summary>
        /// 备用邮箱是否已验证
        /// </summary>
        public bool AlternateEmailConfirmed { get; set; }

        /// <summary>
        /// 工作电话
        /// </summary>
        [Phone]
        [StringLength(32)]
        public string WorkPhone { get; set; }

        /// <summary>
        /// 家庭住址
        /// </summary>
        [StringLength(512)]
        public string HomeAddress { get; set; }

        /// <summary>
        /// 工作地址
        /// </summary>
        [StringLength(512)]
        public string WorkAddress { get; set; }

        #endregion

        #region Keycloak集成

        /// <summary>
        /// Keycloak用户ID
        /// </summary>
        [StringLength(128)]
        public string KeycloakUserId { get; set; }

        /// <summary>
        /// Keycloak Realm名称
        /// </summary>
        [StringLength(128)]
        public string KeycloakRealm { get; set; }

        /// <summary>
        /// Keycloak客户端ID列表
        /// </summary>
        public virtual List<AppUserClientScope> ClientScopes { get; protected set; } = new();

        /// <summary>
        /// 最后一次Keycloak同步时间
        /// </summary>
        public DateTime? LastKeycloakSyncTime { get; set; }

        /// <summary>
        /// 是否启用Keycloak同步
        /// </summary>
        public bool EnableKeycloakSync { get; set; } = true;

        #endregion

        #region 安全相关

        /// <summary>
        /// 最后登录时间
        /// </summary>
        public DateTime? LastLoginTime { get; set; }

        /// <summary>
        /// 最后登录IP地址
        /// </summary>
        [StringLength(64)]
        public string LastLoginIpAddress { get; set; }

        /// <summary>
        /// 最后登录设备信息
        /// </summary>
        [StringLength(512)]
        public string LastLoginDevice { get; set; }

        /// <summary>
        /// 密码最后修改时间
        /// </summary>
        public DateTime? PasswordLastChangedTime { get; set; }

        /// <summary>
        /// 账户锁定结束时间
        /// </summary>
        public DateTime? LockoutEnd { get; set; }

        /// <summary>
        /// 登录失败次数
        /// </summary>
        public int AccessFailedCount { get; set; }

        /// <summary>
        /// 是否启用双因子认证
        /// </summary>
        public bool TwoFactorEnabled { get; set; }

        /// <summary>
        /// 双因子认证密钥
        /// </summary>
        [StringLength(64)]
        public string TwoFactorKey { get; set; }

        /// <summary>
        /// 双因子认证备用码
        /// </summary>
        public virtual List<UserTwoFactorRecoveryCode> TwoFactorRecoveryCodes { get; protected set; } = new();

        #endregion

        #region 个性化设置

        /// <summary>
        /// 用户时区
        /// </summary>
        [StringLength(64)]
        public string TimeZone { get; set; } = "UTC";

        /// <summary>
        /// 用户语言
        /// </summary>
        [StringLength(16)]
        public string Language { get; set; } = "zh-CN";

        /// <summary>
        /// 用户主题
        /// </summary>
        [StringLength(32)]
        public string Theme { get; set; } = "default";

        /// <summary>
        /// 用户偏好设置
        /// </summary>
        public virtual UserPreferences Preferences { get; set; } = new UserPreferences();

        /// <summary>
        /// 用户权限范围
        /// </summary>
        public virtual List<UserPermissionScope> PermissionScopes { get; protected set; } = new();

        #endregion

        #region 审计字段

        /// <summary>
        /// 创建时间
        /// </summary>
        public DateTime CreationTime { get; set; }

        /// <summary>
        /// 创建者ID
        /// </summary>
        public Guid? CreatorId { get; set; }

        /// <summary>
        /// 最后修改时间
        /// </summary>
        public DateTime? LastModificationTime { get; set; }

        /// <summary>
        /// 最后修改者ID
        /// </summary>
        public Guid? LastModifierId { get; set; }

        /// <summary>
        /// 是否已删除
        /// </summary>
        public bool IsDeleted { get; set; }

        /// <summary>
        /// 删除时间
        /// </summary>
        public DateTime? DeletionTime { get; set; }

        /// <summary>
        /// 删除者ID
        /// </summary>
        public Guid? DeleterId { get; set; }

        #endregion

        #region 业务方法

        /// <summary>
        /// 添加客户端Scope
        /// </summary>
        /// <param name="clientId">客户端ID</param>
        /// <param name="scopeName">Scope名称</param>
        public void AddClientScope(string clientId, string scopeName)
        {
            if (ClientScopes.Exists(x => x.ClientId == clientId && x.ScopeName == scopeName))
            {
                return; // 已存在
            }

            ClientScopes.Add(new AppUserClientScope
            {
                ClientId = clientId,
                ScopeName = scopeName,
                GrantedAt = DateTime.UtcNow
            });
        }

        /// <summary>
        /// 移除客户端Scope
        /// </summary>
        /// <param name="clientId">客户端ID</param>
        /// <param name="scopeName">Scope名称</param>
        public void RemoveClientScope(string clientId, string scopeName)
        {
            ClientScopes.RemoveAll(x => x.ClientId == clientId && x.ScopeName == scopeName);
        }

        /// <summary>
        /// 添加权限范围
        /// </summary>
        /// <param name="resourceType">资源类型</param>
        /// <param name="resourceId">资源ID</param>
        /// <param name="permissions">权限列表</param>
        public void AddPermissionScope(string resourceType, Guid resourceId, List<string> permissions)
        {
            PermissionScopes.RemoveAll(x => x.ResourceType == resourceType && x.ResourceId == resourceId);

            PermissionScopes.Add(new UserPermissionScope
            {
                ResourceId = resourceId,
                ResourceName = resourceType,
                Permissions = permissions,
                GrantedAt = DateTime.UtcNow
            });
        }

        /// <summary>
        /// 移除权限范围
        /// </summary>
        /// <param name="resourceType">资源类型</param>
        /// <param name="resourceId">资源ID</param>
        public void RemovePermissionScope(string resourceType, Guid resourceId)
        {
            PermissionScopes.RemoveAll(x => x.ResourceType == resourceType && x.ResourceId == resourceId);
        }

        /// <summary>
        /// 检查用户是否有指定权限
        /// </summary>
        /// <param name="resourceType">资源类型</param>
        /// <param name="resourceId">资源ID</param>
        /// <param name="permission">权限</param>
        /// <returns>是否有权限</returns>
        public bool HasPermission(string resourceType, Guid resourceId, string permission)
        {
            var permissionScope = PermissionScopes.Find(x => x.ResourceType == resourceType && x.ResourceId == resourceId);
            return permissionScope?.Permissions.Contains(permission) ?? false;
        }

        /// <summary>
        /// 更新最后登录信息
        /// </summary>
        /// <param name="ipAddress">IP地址</param>
        /// <param name="device">设备信息</param>
        public void UpdateLastLogin(string ipAddress, string device = null)
        {
            LastLoginTime = DateTime.UtcNow;
            LastLoginIpAddress = ipAddress;
            LastLoginDevice = device;
        }

        /// <summary>
        /// 锁定账户
        /// </summary>
        /// <param name="duration">锁定时长</param>
        public void LockAccount(TimeSpan duration)
        {
            LockoutEnd = DateTime.UtcNow.Add(duration);
            Status = UserStatus.Locked;
        }

        /// <summary>
        /// 解锁账户
        /// </summary>
        public void UnlockAccount()
        {
            LockoutEnd = null;
            AccessFailedCount = 0;
            Status = UserStatus.Active;
        }

        /// <summary>
        /// 更新Keycloak同步信息
        /// </summary>
        /// <param name="keycloakUserId">Keycloak用户ID</param>
        /// <param name="realm">Realm名称</param>
        public void UpdateKeycloakInfo(string keycloakUserId, string realm)
        {
            KeycloakUserId = keycloakUserId;
            KeycloakRealm = realm;
            LastKeycloakSyncTime = DateTime.UtcNow;
        }

        #endregion

        protected AppUser()
        {
        }

        public AppUser(
            Guid id,
            string userName,
            string email) : base(id, userName, email)
        {
            CreationTime = DateTime.UtcNow;
            Status = UserStatus.Active;
            UserType = UserType.Regular;
        }

        public AppUser(
            Guid id,
            string userName,
            string email,
            string phoneNumber) : base(id, userName, email, phoneNumber)
        {
            CreationTime = DateTime.UtcNow;
            Status = UserStatus.Active;
            UserType = UserType.Regular;
            PhoneNumber = phoneNumber;
        }
    }

    /// <summary>
    /// 用户状态枚举
    /// </summary>
    public enum UserStatus
    {
        /// <summary>
        /// 活跃
        /// </summary>
        Active = 0,

        /// <summary>
        /// 未激活
        /// </summary>
        Inactive = 1,

        /// <summary>
        /// 已锁定
        /// </summary>
        Locked = 2,

        /// <summary>
        /// 已暂停
        /// </summary>
        Suspended = 3,

        /// <summary>
        /// 等待验证
        /// </summary>
        PendingVerification = 4,

        /// <summary>
        /// 已禁用
        /// </summary>
        Disabled = 5
    }

    /// <summary>
    /// 用户类型枚举
    /// </summary>
    public enum UserType
    {
        /// <summary>
        /// 普通用户
        /// </summary>
        Regular = 0,

        /// <summary>
        /// 管理员
        /// </summary>
        Administrator = 1,

        /// <summary>
        /// 系统用户
        /// </summary>
        System = 2,

        /// <summary>
        /// 服务账户
        /// </summary>
        Service = 3,

        /// <summary>
        /// 临时用户
        /// </summary>
        Temporary = 4,

        /// <summary>
        /// 访客用户
        /// </summary>
        Guest = 5
    }
}